# -*- coding: utf-8 -*-
"""
余料管理系统工具函数
提供系统中常用的辅助函数
"""

import frappe
from frappe import _
from datetime import datetime, timedelta
import json

def get_scrap_material_details(scrap_material_id):
    """
    获取余料详细信息
    
    Args:
        scrap_material_id (str): 余料ID
        
    Returns:
        dict: 余料详细信息
    """
    if not scrap_material_id:
        return {}
    
    try:
        scrap_material = frappe.get_doc("Scrap Material", scrap_material_id)
        return {
            "material_type": scrap_material.material_type,
            "material_name": scrap_material.material_name,
            "color": scrap_material.color,
            "length": scrap_material.length,
            "width": scrap_material.width,
            "thickness": scrap_material.thickness,
            "quantity": scrap_material.quantity,
            "unit": scrap_material.unit,
            "unit_price": scrap_material.unit_price,
            "warehouse": scrap_material.warehouse,
            "location": scrap_material.location,
            "status": scrap_material.status
        }
    except Exception as e:
        frappe.log_error(f"获取余料详情失败: {str(e)}", "余料管理系统")
        return {}

def get_location_filter_for_pickup_list():
    """
    获取余料待取清单的库位过滤器
    
    Returns:
        dict: 库位过滤器
    """
    filters = []
    
    # 只获取有可用余料的库位
    locations_with_scrap = frappe.db.get_all("Scrap Material", 
        filters={"status": ["!=", "Consumed"]},
        fields=["distinct location"]
    )
    
    if locations_with_scrap:
        location_names = [loc.location for loc in locations_with_scrap]
        filters.append(["Scrap Location", "name", "in", location_names])
    
    # 只获取启用的库位
    filters.append(["Scrap Location", "disabled", "=", 0])
    
    return {"filters": filters}

def get_location_filter_for_batch_material_list():
    """
    获取批次领料清单的库位过滤器
    
    Returns:
        dict: 库位过滤器
    """
    filters = []
    
    # 只获取有可用余料的库位
    locations_with_scrap = frappe.db.get_all("Scrap Material", 
        filters={"status": ["!=", "Consumed"]},
        fields=["distinct location"]
    )
    
    if locations_with_scrap:
        location_names = [loc.location for loc in locations_with_scrap]
        filters.append(["Scrap Location", "name", "in", location_names])
    
    # 只获取启用的库位
    filters.append(["Scrap Location", "disabled", "=", 0])
    
    return {"filters": filters}

def get_default_permissions_for_doctype(doctype, role):
    """
    获取指定DocType和角色的默认权限
    
    Args:
        doctype (str): DocType名称
        role (str): 角色名称
        
    Returns:
        dict: 权限设置
    """
    from scrap_management.permissions import SCRAP_MANAGEMENT_PERMISSIONS
    
    if role in SCRAP_MANAGEMENT_PERMISSIONS and doctype in SCRAP_MANAGEMENT_PERMISSIONS[role]["permissions"]:
        return SCRAP_MANAGEMENT_PERMISSIONS[role]["permissions"][doctype]
    
    # 默认权限
    return {
        "read": 1,
        "write": 0,
        "create": 0,
        "delete": 0,
        "submit": 0,
        "cancel": 0,
        "amend": 0
    }

def calculate_total_quantity(scrap_materials):
    """
    计算余料总数量
    
    Args:
        scrap_materials (list): 余料列表
        
    Returns:
        float: 总数量
    """
    total = 0
    for material in scrap_materials:
        if material.get("quantity"):
            total += float(material.get("quantity"))
    return total

def calculate_total_amount(scrap_materials):
    """
    计算余料总金额
    
    Args:
        scrap_materials (list): 余料列表
        
    Returns:
        float: 总金额
    """
    total = 0
    for material in scrap_materials:
        if material.get("amount"):
            total += float(material.get("amount"))
    return total

def generate_scrap_transaction_id(transaction_type):
    """
    生成余料事务ID
    
    Args:
        transaction_type (str): 事务类型 (Receipt, Issue, Pickup, Batch)
        
    Returns:
        str: 事务ID
    """
    prefix = {
        "Receipt": "SCR-REC",
        "Issue": "SCR-ISS",
        "Pickup": "SCR-PICK",
        "Batch": "SCR-BATCH"
    }.get(transaction_type, "SCR")
    
    # 获取当前日期
    today = datetime.now().strftime("%Y%m%d")
    
    # 获取当天的事务数量
    count = frappe.db.count("Scrap Transaction", {
        "transaction_type": transaction_type,
        "transaction_date": [">=", today],
        "transaction_date": ["<", (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")]
    })
    
    # 生成序列号
    sequence = str(count + 1).zfill(4)
    
    return f"{prefix}-{today}-{sequence}"

def validate_scrap_material_availability(scrap_material_id, required_quantity):
    """
    验证余料可用性
    
    Args:
        scrap_material_id (str): 余料ID
        required_quantity (float): 需要的数量
        
    Returns:
        bool: 是否可用
    """
    if not scrap_material_id or not required_quantity:
        return False
    
    try:
        scrap_material = frappe.get_doc("Scrap Material", scrap_material_id)
        
        # 检查余料状态
        if scrap_material.status == "Consumed":
            frappe.throw(f"余料 {scrap_material.name} 已被消耗，无法使用")
        
        # 检查余料数量
        if float(scrap_material.quantity) < float(required_quantity):
            frappe.throw(f"余料 {scrap_material.name} 数量不足，当前可用数量: {scrap_material.quantity}，需要数量: {required_quantity}")
        
        return True
    except Exception as e:
        frappe.log_error(f"验证余料可用性失败: {str(e)}", "余料管理系统")
        return False

def update_scrap_material_quantity(scrap_material_id, quantity_change, transaction_type=None, reference_doc=None):
    """
    更新余料数量
    
    Args:
        scrap_material_id (str): 余料ID
        quantity_change (float): 数量变化（正数为增加，负数为减少）
        transaction_type (str): 事务类型
        reference_doc (str): 参考文档
        
    Returns:
        bool: 是否成功
    """
    if not scrap_material_id or quantity_change == 0:
        return False
    
    try:
        scrap_material = frappe.get_doc("Scrap Material", scrap_material_id)
        old_quantity = float(scrap_material.quantity)
        new_quantity = old_quantity + float(quantity_change)
        
        # 更新数量
        scrap_material.quantity = new_quantity
        
        # 更新状态
        if new_quantity <= 0:
            scrap_material.status = "Consumed"
        elif old_quantity <= 0 and new_quantity > 0:
            scrap_material.status = "Available"
        
        scrap_material.save(ignore_permissions=True)
        
        # 创建事务记录
        if transaction_type:
            create_scrap_transaction(
                scrap_material_id=scrap_material_id,
                transaction_type=transaction_type,
                quantity_change=quantity_change,
                old_quantity=old_quantity,
                new_quantity=new_quantity,
                reference_doc=reference_doc
            )
        
        return True
    except Exception as e:
        frappe.log_error(f"更新余料数量失败: {str(e)}", "余料管理系统")
        return False

def create_scrap_transaction(scrap_material_id, transaction_type, quantity_change, old_quantity, new_quantity, reference_doc=None):
    """
    创建余料事务记录
    
    Args:
        scrap_material_id (str): 余料ID
        transaction_type (str): 事务类型
        quantity_change (float): 数量变化
        old_quantity (float): 旧数量
        new_quantity (float): 新数量
        reference_doc (str): 参考文档
        
    Returns:
        str: 事务记录ID
    """
    try:
        transaction = frappe.get_doc({
            "doctype": "Scrap Transaction",
            "scrap_material": scrap_material_id,
            "transaction_type": transaction_type,
            "transaction_date": frappe.utils.nowdate(),
            "transaction_time": frappe.utils.nowtime(),
            "quantity_change": quantity_change,
            "old_quantity": old_quantity,
            "new_quantity": new_quantity,
            "reference_document": reference_doc,
            "created_by": frappe.session.user
        })
        transaction.insert(ignore_permissions=True)
        
        return transaction.name
    except Exception as e:
        frappe.log_error(f"创建余料事务记录失败: {str(e)}", "余料管理系统")
        return None

def get_scrap_inventory_summary(warehouse=None, location=None):
    """
    获取余料库存汇总
    
    Args:
        warehouse (str): 仓库ID（可选）
        location (str): 库位ID（可选）
        
    Returns:
        dict: 库存汇总信息
    """
    filters = {"status": ["!=", "Consumed"]}
    
    if warehouse:
        filters["warehouse"] = warehouse
    
    if location:
        filters["location"] = location
    
    # 获取余料汇总
    summary = frappe.db.get_all("Scrap Material",
        filters=filters,
        fields=[
            "material_type",
            "SUM(quantity) as total_quantity",
            "SUM(quantity * unit_price) as total_value",
            "COUNT(*) as count"
        ],
        group_by="material_type"
    )
    
    # 计算总计
    total_quantity = sum(item.get("total_quantity", 0) for item in summary)
    total_value = sum(item.get("total_value", 0) for item in summary)
    total_count = sum(item.get("count", 0) for item in summary)
    
    return {
        "summary": summary,
        "total_quantity": total_quantity,
        "total_value": total_value,
        "total_count": total_count
    }

def send_notification(recipients, subject, message, reference_doc=None):
    """
    发送通知
    
    Args:
        recipients (list): 接收者列表
        subject (str): 主题
        message (str): 消息内容
        reference_doc (str): 参考文档
        
    Returns:
        bool: 是否成功
    """
    try:
        for recipient in recipients:
            frappe.sendmail(
                recipients=[recipient],
                subject=subject,
                message=message,
                reference_doctype=reference_doc.doctype if reference_doc else None,
                reference_name=reference_doc.name if reference_doc else None
            )
        
        return True
    except Exception as e:
        frappe.log_error(f"发送通知失败: {str(e)}", "余料管理系统")
        return False